/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.business.account.core.domain.account;

import cn.hutool.core.date.DateUtil;
import info.peigen.hotpot.business.account.facade.enums.AccountTransCode;
import info.peigen.hotpot.common.core.domain.DomainObject;
import info.peigen.hotpot.common.core.lang.money.Money;
import info.peigen.hotpot.common.core.util.IdUtil;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;

import java.util.Date;

import static info.peigen.hotpot.business.account.facade.enums.AccountTransCode.*;

/**
 * <b>(AccountTransLog)</b>
 * 账务交易流水记录
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/8/12
 */
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Accessors(chain = true)
public class AccountTransLog extends DomainObject {
    /** transLogId */
    @Builder.Default
    String           transLogId = IdUtil.id();
    /** 交易系统订单号 */
    @NotEmpty
    String           tradeId;
    /** 交易代码 */
    @NotNull
    AccountTransCode transCode;
    /** 借记-账务记录 */
    AccountLog debitAccountLog;
    /** 贷记-账务记录 */
    AccountLog creditAccountLog;
    /** 收费[付费账户]账务记录 */
    AccountLog feePayerAccountLog;
    /** 收费[收入账户]账务记录 */
    AccountLog feePayeeAccountLog;
    /** 交易金额-包含币种 */
    @NotNull
    Money transAmount;
    /** 交易时间 */
    @Builder.Default
    Date  transTime = DateUtil.date();
    /** 清算时间-有别与交易时间,应是实际资金清算系统提供的交易完成时间,视为清算时间 */
    @NotNull
    Date  settleTime;
    /** memo */
    String memo;

    public static AccountTransLog depositNoFee(AccountLog creditAccountLog, Money transAmount) {
        return AccountTransLog.builder()
                .creditAccountLog(creditAccountLog)
                .tradeId(creditAccountLog.getTradeId())
                .transCode(Deposit)
                .transAmount(transAmount)
                .settleTime(creditAccountLog.getSettleTime())
                .memo(creditAccountLog.getMemo())
                .build();
    }

    public static AccountTransLog deposit(AccountLog creditAccountLog,
                                          AccountLog feePayerAccountLog, AccountLog feePayeeAccountLog,
                                          Money transAmount) {
        return AccountTransLog.builder()
                .creditAccountLog(creditAccountLog)
                .feePayerAccountLog(feePayerAccountLog)
                .feePayeeAccountLog(feePayeeAccountLog)
                .tradeId(creditAccountLog.getTradeId())
                .transCode(Deposit)
                .transAmount(transAmount)
                .settleTime(creditAccountLog.getSettleTime())
                .memo(creditAccountLog.getMemo())
                .build();
    }

    public static AccountTransLog withdrawNoFee(AccountLog debitAccountLog, Money transAmount) {
        return AccountTransLog.builder()
                .debitAccountLog(debitAccountLog)
                .tradeId(debitAccountLog.getTradeId())
                .transCode(Withdraw)
                .transAmount(transAmount)
                .settleTime(debitAccountLog.getSettleTime())
                .memo(debitAccountLog.getMemo())
                .build();
    }

    public static AccountTransLog withdraw(AccountLog debitAccountLog,
                                           AccountLog feePayerAccountLog, AccountLog feePayeeAccountLog,
                                           Money transAmount) {
        return AccountTransLog.builder()
                .debitAccountLog(debitAccountLog)
                .feePayerAccountLog(feePayerAccountLog)
                .feePayeeAccountLog(feePayeeAccountLog)
                .tradeId(debitAccountLog.getTradeId())
                .transCode(Withdraw)
                .transAmount(transAmount)
                .settleTime(debitAccountLog.getSettleTime())
                .memo(debitAccountLog.getMemo())
                .build();
    }

    public static AccountTransLog transNoFee(AccountLog debitAccountLog, AccountLog creditAccountLog, Money transAmount) {
        return AccountTransLog.builder()
                .debitAccountLog(debitAccountLog)
                .creditAccountLog(creditAccountLog)
                .tradeId(debitAccountLog.getTradeId())
                .transCode(Transfer)
                .transAmount(transAmount)
                .settleTime(debitAccountLog.getSettleTime())
                .memo(debitAccountLog.getMemo())
                .build();
    }

    public static AccountTransLog trans(AccountLog debitAccountLog, AccountLog creditAccountLog,
                                        AccountLog feePayerAccountLog, AccountLog feePayeeAccountLog,
                                        Money transAmount) {
        return AccountTransLog.builder()
                .debitAccountLog(debitAccountLog)
                .creditAccountLog(creditAccountLog)
                .feePayerAccountLog(feePayerAccountLog)
                .feePayeeAccountLog(feePayeeAccountLog)
                .tradeId(debitAccountLog.getTradeId())
                .transCode(Transfer)
                .transAmount(transAmount)
                .settleTime(debitAccountLog.getSettleTime())
                .memo(debitAccountLog.getMemo())
                .build();
    }
}
